<template>
  <div class="upload-wrapper" @click.prevent="triggerUpload">
    <!-- 更改按钮 上传样式状态 点击上传 loading... 上传成功 -->
    <slot name="loading" v-if="uploadStatus === 'loading'">
      <div>loading...</div>
    </slot>
    <slot name="success" :fileData="fileData" v-else>
      <div>点击上传</div>
    </slot>
    <slot name="default">
      <div class="btn btn-primriy">点击上传</div>
    </slot>
    <!-- <slot name="default" v-else>
      <div class="btn btn-primriy">点击上传</div>
    </slot> -->
  </div>
  <input type="file" class="d-none" @change="onChange" ref="fileRef" />
</template>
<script lang="ts">
import { defineComponent, ref, PropType } from 'vue'
import axios from 'axios'

// 设置按钮状态，通过状态判断上传的样式显示
// uploadStatus
// trigger事件触发额外与元素，不能与元素处于同一个盒子内部；
export type uploadStatusProps = 'ready' | 'loading' | 'success' | 'error'
export type FuncBeforeUplaod = (file: any) => boolean
export default defineComponent({
  props: {
    action: {
      type: String as PropType<string>
    },
    // 上传之前的一个校验函数
    beforeUpload: Function as PropType<FuncBeforeUplaod>
  },
  setup(props, context) {
    const fileRef = ref<HTMLInputElement | null>(null)
    const uploadStatus = ref<uploadStatusProps>('ready')
    const fileData = ref<any>('')
    const testData = ref('测试数据展示')
    const triggerUpload = () => {
      if (fileRef.value) {
        console.log('--------value', fileRef.value)
        // 触发事件
        fileRef.value.click()
      }
    }

    const onChange = (e: Event) => {
      const currentTarget = e.target as HTMLInputElement
      const files = currentTarget.files
      if (files) {
        if (props.beforeUpload) {
          const bool = props.beforeUpload(files[0])
          console.log('bool', bool)
          if (!bool) return
        }
        // 设置loading状态。开始上传
        uploadStatus.value = 'loading'
        console.log('e:', files)
        const formData = new FormData()
        formData.append('file', files[0])
        console.log('formData:', formData)
        if (props.action) {
          axios
            .post(props.action, formData, {
              headers: {
                'Content-Type': 'multipart/form-data'
              }
            })
            .then((fileResponse) => {
              uploadStatus.value = 'success'
              // 当状态为成功的时候，数据成功赋值；
              fileData.value = fileResponse.data
              console.log('fileResponse:', fileResponse)
              context.emit('uploadedSuccess', fileResponse)
            })
            .catch((error) => {
              uploadStatus.value = 'error'
              context.emit('uploadedError', error)
              console.log('error', error)
            })
            .finally(() => {
              setTimeout(() => {
                uploadStatus.value = 'ready'
              }, 3000)
              // 不管上面怎么执行，最终都会执行这个方法；
              console.log('finally')
            })
        } else {
          console.log('没有action行为')
          context.emit('before-formData', formData)
        }
      }
    }

    return {
      fileRef,
      triggerUpload,
      onChange,
      uploadStatus,
      testData
    }
  }
})
</script>
